﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Network;
using Rappelz.GameServer.Network.GameClient;
using Rappelz.GameServer.Database;

namespace Rappelz.GameServer
{
    public class PetBase
    {
        public enum PetRateBitflag : int
        {
            RateRare = 1,
            RateShovelable = 2,
            RateItemCollectable = 3,
        }

        public int uid;                         // 0x0
        public int type;                        // 0x4
        public int name_id;                     // 0x8
        public int cage_id;                     // 0xC
        public int attribute_flag;                      // 0x10
        public float size;                      // 0x14
        public float scale;                     // 0x18
    }

    public class Pet : Creature
    {
// Enum           :   <unnamed-tag>, Type: int
// Data           :     constant 0x46, Constant, Type: int, PET_SPAWN_LENGTH
// Data           :     constant 0x18, Constant, Type: int, PET_SPAWN_MIN_LENGTH
        public enum ShovelingStatus : int
        {
            Idle = 0,
            Search = 1,
            Approach = 2,
            Dig = 3,
        }

// Function       :   public static void BindProperty()
        public static Pet AllocPet(Player player, uint code)
        {
            Pet pet = MemoryPool.AllocPet();
            pet.m_nSID = 0;
            pet.m_bNameChanged = true;
            pet.m_nArObjectType = 1;
            pet.SetPetInfo(code);
            pet.m_nHP = 100;
            pet.m_nMaxHP = 100;
            pet.m_fMP = 100;
            pet.m_nMaxMP = 100;
            pet.m_bIsSummoned = false;
            pet.m_master = player;
            pet.m_item = null;
            pet.m_szName = "";
            pet.m_nLastProcessTime = 0;
            pet.m_nShovelingStatus = 0;
            pet.mv.face = ((float)Globals.GetRandomInt32()) / 100.0f;
            //XSEH::IncreaseAllocCount("StructPet", 1);

            pet.SetSkill(-5, 6907, 1, 0);
            return pet;
        }
// Function       :   public static void StructPet::FreePet(struct StructPet *)

// Function       :   public bool StructPet::IsDeleteable()
// Function       :   public bool StructPet::IsEnemy()
// Function       :   public bool StructPet::IsAlly(struct StructCreature *)
        public bool SetPetInfo(uint code)
        {
            this.m_ContentInfo = GameContent.GetPetInfo((int)code);
            return this.m_ContentInfo != null;
        }

        public PetBase GetPetBase()
        {
            return this.m_ContentInfo;
        }

// Function       :   public int GetPetCode()
// Function       :   public int GetNameID()

        public override int GetCreatureGroup()
        {
            return this.m_ContentInfo.type;
        }
// Function       :   public unsigned char StructPet::GetRace()

        public override bool IsPet()
        {
            return true;
        }

// Function       :   public void SetPetSID(int)
// Function       :   public int GetPetSID()
// Function       :   public int StructPet::GetSID()
        public void SetName(int nNameId)
        {
            this.m_szName = GameContent.GetString(nNameId);
        }

        public void SetName(string name)
        {
            this.m_szName = name;
        }
// Function       :   public const char * GetPetName()

        public override string GetName()
        {
            return this.m_szName;
        }
// Function       :   public void SetNameChanged(const bool)
// Function       :   public const bool IsNameChanged()

        public ushort ChangeName(string szName)
        {
            ushort result = 0;

            if (this.m_bNameChanged)
            {
                result = 5;
            }
            else
            {
                if (szName.Length < 18)
                {
                    if (szName.Length >= 4 )
                    {
                        if (!GameRule.IsValidName(szName, 19, 4, 18) || GameContent.IsBannedWord(szName))
                        {
                            result = 6;
                        }
                        else
                        {
                            if(this.m_szName != szName)
                            {
                                this.m_bNameChanged = true;
                                this.m_szName = szName;
                                PacketOut pak = new PacketOut(ClientOutPackets.NameChange);
                                pak.WriteUInt32(this.m_hHandle);
                                pak.FillString(this.m_szName,19);

                                if (this.m_master != null)
                                    this.m_master.Connection.SendTCP(pak);
                                if (this.bIsInWorld )
                                {
                                    RappelzServer.Instance.Broadcast((uint)(this.mv.x / GameContent.g_nRegionSize),
                                        (uint)(this.mv.y / GameContent.g_nRegionSize), this.m_layer, pak);
                                }
                                this.DBQuery(new DB_ChangePetName(this));
                                result = 0;
                            }
                            else
                            {
                                result = 9;
                            }
                        }
                    }
                    else
                    {
                        result = 17;
                    }
                }
                else
                {
                    result = 16;
                }
            }
            return result;

        }
    
// Function       :   public void SetMaster(struct StructPlayer *)
// Function       :   public struct StructPlayer * GetMaster()
// Function       :   public void SetParentCage(struct StructItem *)
// Function       :   public struct StructItem * GetParentCage()
// Function       :   public void SetSummonFlag(bool)
// Function       :   public bool GetSummonFlag()
// Function       :   public float StructPet::GetScale()
// Function       :   public float StructPet::GetSize()
// Function       :   public const bool IsRare()
// Function       :   public const bool IsShovelable()
// Function       :   public const bool IsItemCollectable()
// Function       :   public const enum StructPet::SHOVELING_STATUS GetShovelingStatus()
// Function       :   public void SetShovelingStatus(const enum StructPet::SHOVELING_STATUS)
// Function       :   public void StructPet::OnUpdate()
// Function       :   public bool StructPet::IsAttackable()
// Function       :   public bool StructPet::IsMovable()
// Function       :   public bool StructPet::IsKnockbackable()
// Function       :   public bool StructPet::IsItemUseable()
// Function       :   public bool StructPet::IsItemWearable()
// Function       :   public bool StructPet::IsSkillCastable()
// Function       :   public bool StructPet::IsMagicCastable()
// Function       :   public void StructPet::DBQuery(struct GameDBManager::DBProc *)
// Function       :   public void StructPet::onEndQuery()
// Function       :   public void StructPet::AddExp(__int64, int, bool)
// Function       :   public void StructPet::SetLevel(int)
// Function       :   public int StructPet::GetLevel()
// Function       :   public int StructPet::GetJobLevel()
// Function       :   public int StructPet::GetStatId()
// Function       :   public int StructPet::GetJobId()
// Function       :   public void StructPet::SetPrevJobLevel(int, int)
// Function       :   public int StructPet::GetPrevJobLevel(int)
// Function       :   public void StructPet::SetPrevJobId(int, int)
// Function       :   public int StructPet::GetPrevJobId(int)
// Function       :   public void StructPet::SetJobLevel(int)
// Function       :   public int StructPet::GetJobDepth()
// Function       :   public int StructPet::GetJobPoint()
// Function       :   public int StructPet::GetTotalJobPoint()
// Function       :   public int StructPet::GetItemChance()
// Function       :   public bool StructPet::IsUsingBow()
// Function       :   public bool StructPet::IsUsingCrossBow()
        public override float GetBattleLevel()
        {
            return 0.0f;
        }
// Function       :   public const __int64 StructPet::GetBulletCount()
// Function       :   public struct StructItem * StructPet::GetWearedItem(enum ItemBase::ItemWearType)
// Function       :   public enum ItemBase::ItemWearType StructPet::GetAbsoluteWearPos(enum ItemBase::ItemWearType &)
        public override bool TranslateWearPosition(ref ItemBase.ItemWearType pos, Item item, ref List<int> ItemList)
        {
            return false;
        }

// Function       :   public unsigned long StructPet::GetNextAttackableTime()
// Function       :   public void StructPet::SetNextAttackableTime(unsigned long)
// Function       :   public bool StructPet::StartAttack(unsigned int, bool)
// Function       :   public void StructPet::CancelAttack()
// Function       :   public void StructPet::EndAttack()
// Function       :   public void StructPet::onAttack(struct StructCreature *, int)
// Function       :   public int StructPet::onDamage(struct StructCreature *, enum Elemental::Type, enum StructCreature::DamageType, int, bool)
// Function       :   public bool StructPet::IsBattleMode()
// Function       :   public const struct CreatureStat & StructPet::GetBaseStat()
// Function       :   public float StructPet::GetFCM()
// Function       :   public int StructPet::GetMoveSpeed()
// Function       :   protected bool StructPet::ProcDelete()
// Function       :   protected void StructPet::onChangeProperty(const class std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, const char *)
// Function       :   protected const char * StructPet::getClassName()
// Function       :   protected void StructPet::onProcess(int)
// Function       :   protected void StructPet::processWalk(unsigned long)
// Function       :   public void StructPet(const struct StructPet &)
// Function       :   protected void StructPet::StructPet(unsigned int, unsigned int)
// Function       :   protected void StructPet(const char *)
// Function       :   protected void StructPet::~StructPet()
        protected override void applyState(State state)
        {

        }

// Function       :   protected void StructPet::applyStateAmplify(struct StructState &)
// Function       :   protected void StructPet::incParameter(int, int, bool)
// Function       :   protected void StructPet::ampParameter(int, class c_fixed<10000>, bool)
// Function       :   protected void StructPet::incParameter2(int, class c_fixed<10000>)
// Function       :   protected void StructPet::ampParameter2(int, class c_fixed<10000>)
// Function       :   protected unsigned short StructPet::putonItem(enum ItemBase::ItemWearType, struct StructItem *)
// Function       :   protected unsigned short StructPet::putoffItem(enum ItemBase::ItemWearType)
        protected override void calcAttribute(CreatureAttributeServer attribute)
        {

        }

        protected override void applyStatByState()
        {

        }
// Function       :   protected void StructPet::amplifyStatByState()
        protected override void applyJobLevelBonus()
        {

        }
        
        protected override void applyPassiveSkillEffect(Skill skill)
        {

        }

        protected override void applyPassiveSkillEffect()
        {

        }

        protected override void applyPassiveSkillAmplifyEffect(Skill skill)
        {

        }

        protected override void applyPassiveSkillAmplifyEffect()
        {

        }

// Function       :   protected void StructPet::onItemWearEffect(struct StructItem *, bool, int, class c_fixed<10000>, class c_fixed<10000>, float)
// Function       :   protected void StructPet::onBeforeCalculateStat()
        protected override void onAfterApplyStat()
        {

        }

        protected override void onApplyStat()
        {

        }

        protected override void onAfterCalculateAttributeByStat()
        {

        }

        protected override void onModifyStatAndAttribute()
        {

        }

        protected override void onCompleteCalculateStat()
        {

        }
// Function       :   protected void StructPet::onAfterAddState(struct StructState &)
// Function       :   protected void StructPet::onAfterRemoveState(struct StructState &)
// Function       :   protected void StructPet::onUpdateState(struct StructState &, bool)
// Function       :   protected void StructPet::onCantAttack(unsigned int, unsigned long)
// Function       :   protected void StructPet::onDead(struct StructCreature *, bool)
// Function       :   protected void StructPet::onJobLevelUp()
// Function       :   protected void StructPet::onExpChange()
// Function       :   protected void StructPet::onMaxHavocChange()
// Function       :   protected void StructPet::onHavocChange()
// Function       :   protected void StructPet::onEnergyChange()
// Function       :   protected void StructPet::onRegisterSkill(int, int, int, int)
// Function       :   protected void StructPet::onStatChange()
// Function       :   protected void StructPet::onAttributeChange()
// Function       :   protected void StructPet::onHPChange(int)
// Function       :   protected void StructPet::onMPChange()
// Function       :   protected void StructPet::onSPChange()
// Function       :   protected int StructPet::getJPAfterSkillReset()
// Function       :   protected void StructPet::onBeforeResetSkill()
// Function       :   protected void StructPet::onAfterResetSkill()
        public Player m_master;                                                 // 0xFE4
        public Item m_item;                                                     // 0xFE8
        public PetBase m_ContentInfo = new PetBase();                           // 0xFEC
        public bool m_bIsSummoned;                                              // 0xFF0
//        public uint m_hHandle;                                                  // 0xFF4
        public int m_nSID;                                                      // 0xFF8
        public string m_szName;                                                 // 0xFFC
        public bool m_bNameChanged;                                             // 0x100F
        public uint m_nLastProcessTime;                                         // 0x1010
        public ShovelingStatus m_nShovelingStatus;                              // 0x1014
// Data           :   this+0x1058, Member, Type: class std::list<GameDBManager::DBProc *,std::allocator<GameDBManager::DBProc *> >, m_lQueryList
    }
}
